﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.Collections;


namespace EnumUtils.Extensions
{
  public static class FlagEnumExtensions
  {
    /// <summary>
    /// Bit shifts the flag enum bit pattern leftward.
    /// </summary>
    /// 
    /// <param name="bitPattern">Flag enum instance to bit-shift on (is NOT modified)</param>
    /// 
    /// <param name="timesToShift">The number of times to shift the bit pattern.</param>
    /// 
    /// <returns></returns>
    /// 
    /// <exception cref="ArgumentException">
    /// Thrown when bitPattern is not a Flags enum.
    /// </exception>
    public static Enum
    BitShiftLeft( this Enum bitPattern, int timesToShift ) {
      Contract.Requires<ArgumentException>(EnumFlagsUtilities.DoesEnumHaveFlagsAttribute(bitPattern), ErrorMessageUtils.EnumNotAFlagsEnumMessage);
//LEFT_OFF_HERE: Determine what to do in the case that a bit shift goes past the larget flag.
      int enumAsAnInt = Convert.ToInt32(bitPattern);
      enumAsAnInt <<= timesToShift;
      Enum result = EnumFlagsUtilities.ConvertIntToEnum(bitPattern.GetType(), enumAsAnInt);

      return result;
    }



    /// <summary>
    /// Bit shifts the flag enum bit pattern rightward.
    /// </summary>
    /// 
    /// <param name="bitPattern"></param>
    /// 
    /// <param name="timesToShift">The number of times to shift the bit pattern.</param>
    /// 
    /// <returns></returns>
    public static Enum
    BitShiftRight( this Enum bitPattern, int timesToShift ) {
      Contract.Requires<ArgumentException>(EnumFlagsUtilities.DoesEnumHaveFlagsAttribute(bitPattern), ErrorMessageUtils.EnumNotAFlagsEnumMessage);

      int enumAsAnInt = Convert.ToInt32(bitPattern);
      enumAsAnInt >>= timesToShift;
      // RJM: Question: what if timesToShift was negative?
      Enum result = EnumFlagsUtilities.ConvertIntToEnum(bitPattern.GetType(), enumAsAnInt);

      return result;
    }
  }
}
